import React, {useCallback, useContext, useState, useEffect, useRef} from 'react';
import {QuestionCircleFilled} from '@ant-design/icons';
import {Form} from '@ant-design/compatible';
import '@ant-design/compatible/assets/index.css';
import {Row, Col, Button, Select, Spin, message, Popover} from 'antd';
import {throttle} from 'lodash';
import {connect} from 'react-redux';

import {PAGER, SEARCH_WAIT_TIME, INCLUDE} from '~/utils/const';
import {
    getFieldValueApi,
    getImportanceList
} from '~/service/performance';
import searchParam from '~/model/searchParam';

import {popUpContainer} from '../../utils';
import {FormContext} from './FormStore';
import ENV_DESC from './envDesc';

const {Option} = Select;

// eslint-disable-next-line max-lines-per-function
const SearchForm = props => {
    const {dispatch: reduxDispatch} = props;
    const clientTypeList = [...INCLUDE.keys()];
    const {
        form: {
            getFieldDecorator,
            validateFields,
            resetFields,
        },
        submit,
        resetFun,
    } = props;
    const [showLoading, setShowLoading] = useState(false);

    const pathKeyWord = useRef('');
    const pathMaxCount = useRef(0);
    const {
        state: {business, businessList, project, projectList, path, pathList, pathScrollPage},
        dispatch
    } = useContext(FormContext);

    // 查询按钮
    const onSubmit = useCallback(() => {
        validateFields(error => {
            if (!error) {
                // update redux store search
                const param = {
                    business,
                    businessList,
                    project,
                    projectList,
                    path,
                    pathList
                };
                reduxDispatch(searchParam.setInfo({
                    system: 'analysis',
                    data: param
                }));

                submit();
            }
        });
    });

    const getBusinessList = async (type, params) => {
        setShowLoading(true);
        const res = await getFieldValueApi(params);
        setShowLoading(false);
        if (res === null) {
            return;
        }
        const data = res.data.values;
        switch (type) {
            case 'business':
                dispatch({
                    type: 'changeBusinessList',
                    data
                });
                break;
            case 'project':
                dispatch({
                    type: 'changeProjectList',
                    data
                });
                break;
            case 'path':
                pathMaxCount.current = res.pager.count;
                dispatch({
                    type: 'changePathList',
                    data
                });
                break;
        }
    };
    const onChangeBusiness = useCallback(business => {
        pathMaxCount.current = 0;
        dispatch({
            type: 'changeBusiness',
            data: {
                business
            }
        });
        resetFields(['selectedProject', 'selectedPath']);
        getBusinessList('project', {
            field: 'biz_name',
            bizTypeName: business
        });
    }, []);

    const onChangeProject = useCallback(project => {
        pathMaxCount.current = 0;
        dispatch({
            type: 'changeProject',
            data: {
                project
            }
        });
        resetFields(['selectedPath']);
        getBusinessList('path', {
            field: 'path',
            bizTypeName: business,
            bizName: project
        });
    }, [business]);

    // 当flag 为 true 时不要修改path值
    // 下拉输入搜索func
    const getPathFieldValue = async (type, pageNum, flag) => {
        if (pathList.length === pathMaxCount.current && type === 'scroll') {
            return;
        }
        const res = await getFieldValueApi({
            field: 'path',
            bizTypeName: business,
            bizName: project,
            keyword: pathKeyWord.current,
            pager: {...PAGER, pageNum}
        });
        if (res === null) {
            return;
        }
        const list = res.data.values;
        // eslint-disable-next-line require-atomic-updates
        pathMaxCount.current = res.pager.count;
        if (list.length === 0) {
            resetFields(['selectedPath']);
            dispatch({
                type: 'changePathList',
                data: {
                    pathList: [],
                    pathScrollPage: pageNum,
                    flag
                }
            });
            return;
        }
        dispatch({
            type: 'changePathList',
            data: {
                pathList: type === 'scroll' && pageNum !== 1 ? pathList.concat(list) : list,
                pathScrollPage: pageNum,
                flag
            }
        });
    };
    // 选择path后触发
    const onChangePath = useCallback(path => {
        pathKeyWord.current = '';
        dispatch({
            type: 'changePath',
            data: {
                path
            }
        });
    }, [business, project, pathList]);
    // 下拉按需加载
    const onPathPopupScroll = useCallback(e => {
        e.persist();
        const {target} = e;
        if (target.scrollTop + target.offsetHeight === target.scrollHeight) {
            const nextScrollPage = pathScrollPage + 1;
            getPathFieldValue('scroll', nextScrollPage);
        }
    }, [business, project, path, pathList, pathScrollPage]);
    const onSearchPath = useCallback(throttle(keyword => {
        pathKeyWord.current = keyword;
        getPathFieldValue('search', 1, true);
    }, SEARCH_WAIT_TIME, {leading: false}), [business, project, pathList]);
    const selectorFactoryConfig = [
        {
            label: '业务线',
            field: 'selectedBusiness',
            message: ' ',
            onChange: onChangeBusiness,
            list: businessList,
            ...(business && {
                initialValue: business
            })
        },
        {
            label: '应用',
            field: 'selectedProject',
            message: ' ',
            onChange: onChangeProject,
            list: projectList,
            ...(project && {
                initialValue: project
            })
        },
        {
            label: '路径',
            field: 'selectedPath',
            message: ' ',
            onChange: onChangePath,
            list: pathList,
            onPopupScroll: onPathPopupScroll,
            onSearch: onSearchPath,
            ...(path && {
                initialValue: path
            })
        }
    ];

    useEffect(() => {
        getBusinessList('business', {
            field: 'biz_type_name'
        });
    }, []);

    // path修改后 api修改sortedTargetTypes
    useEffect(() => {
        if (path !== null) {
            importanceListApi();
        }
        async function importanceListApi() {
            if (business && project && path) {
                const data = {
                    bizTypeName: business,
                    bizName: project,
                    path,
                };
                const res = await getImportanceList(data);
                if (res.code === 0) {
                    dispatch({
                        type: 'changeSorted',
                        data: res.data.sortedTargetTypes
                    });
                }
                else {
                    message.error(res.msg);
                }
            }
        }
    }, [path]);

    // 重置按钮
    const onReset = useCallback(() => {
        dispatch({
            type: 'reset',
        });

        // update redux store search
        reduxDispatch(searchParam.reset('analysis'));

        resetFields();
        resetFun();
    }, []);

    function onChangeClientType(data) {
        dispatch({
            type: 'changeClientType',
            data
        });
    }

    return (
        <Spin spinning={showLoading}>
            <Form layout="inline">
                <Row>
                    {
                        selectorFactoryConfig.map((
                            {label, field, initialValue, message, onChange, list, onPopupScroll, onSearch, value}
                        ) => (
                            <Col span={8} key={`${field}col`}>
                                <Form.Item
                                    key={field}
                                    label={label}
                                    labelAlign="right"
                                >
                                    {
                                        getFieldDecorator(field, {
                                            initialValue,
                                            rules: [
                                                {
                                                    required: true,
                                                    message,
                                                },
                                            ],
                                        })(
                                            <Select
                                                className="user-feature-select"
                                                placeholder="请选择"
                                                notFoundContent="暂无数据"
                                                showSearch
                                                optionFilterProp="children"
                                                getPopupContainer={popUpContainer}
                                                onChange={onChange}
                                                onPopupScroll={onPopupScroll}
                                                onSearch={onSearch}
                                                filterOption={field !== 'selectedPath'}
                                                style={{width: '240px'}}
                                            >
                                                {
                                                    list.map((item, index) => (
                                                        <Option key={item} value={item} title={item}>
                                                            {item}
                                                        </Option>
                                                    ))
                                                }
                                            </Select>
                                        )
                                    }
                                </Form.Item>
                            </Col>
                        ))
                    }
                </Row>
                <Row>
                    <Col span={8} key="selectedClientTypecol">
                        <Form.Item
                            key="selectedClientType"
                            label="宿主环境"
                            labelAlign="right"
                        >
                            {
                                getFieldDecorator('selectedClientType', {
                                    initialValue: 0,
                                    rules: [
                                        {
                                            required: true,
                                            message: ' ',
                                        },
                                    ],
                                })(
                                    <Select
                                        className="env-select"
                                        placeholder="请选择"
                                        notFoundContent="暂无数据"
                                        getPopupContainer={popUpContainer}
                                        onChange={onChangeClientType}
                                        style={{width: '240px'}}
                                    >
                                        <Option key="0" value={0}>
                                            全部
                                        </Option>
                                        {
                                            clientTypeList.map((item, index) => (
                                                <Option key={item} value={item}>
                                                    {INCLUDE.get(item)}
                                                </Option>
                                            ))
                                        }
                                    </Select>
                                )
                            }
                            <Popover content={ENV_DESC} overlayClassName="analysisPopover">
                                <QuestionCircleFilled />
                            </Popover>
                        </Form.Item>
                    </Col>
                </Row>
                <Row type="flex" justify="end">
                    <div className="btn-group">
                        <Button
                            type="primary"
                            onClick={onSubmit}
                        >
                            查询
                        </Button>
                        <Button type="default" onClick={onReset}>重置</Button>
                    </div>
                </Row>
            </Form>
        </Spin>
    );
};

export default connect(s => s)(Form.create()(SearchForm));
